/*
 * 16. Write a program to convert a decimal number
 * to binary and vice versa. Add a functionality
 * to support the hexadecimal numeral system.
 * Do not use the Java built-in functionality for
 * numeral systems conversion
 */

package _3;

import java.util.Scanner;

public class _16 {
	public static String dtob (int n) {
		char[] b = new char[32];

		if (n < 0) {
			n = -n;
			b[0] = '1';
		} else
			b[0] = '0';

		for (int i = 30; i >= 0; i--) {
			int tmp = (int) Math.pow (2d, i);

			if (n >= tmp) {
				n -= tmp;
				b[31 - i] = '1';
			} else
				b[31 - i] = '0';
		}

		return new String (b);
	}

	public static String dtoh (int n) {
		char sign;
		char[] h = new char[8];

		if (n < 0) {
			n = -n;
			sign = '-';
		} else
			sign = '+';

		int i = h.length;
		while (n != 0) {
			int tmp = n % 16;

			switch (tmp) {
			case 10:
				h[--i] = 'a';
				break;
			case 11:
				h[--i] = 'b';
				break;
			case 12:
				h[--i] = 'c';
				break;
			case 13:
				h[--i] = 'd';
				break;
			case 14:
				h[--i] = 'e';
				break;
			case 15:
				h[--i] = 'f';
				break;
			default:
				h[--i] = (char) (tmp + '0');
				break;
			}

			n /= 16;
		}

		while (i > 0) {
			h[--i] = '0';
		}

		if (sign == '-')
			return new String (sign + new String (h));
		else
			return new String (h);
	}

	public static int btod (String s) {
		char[] b = s.toCharArray ();
		int res = 0;

		for (int i = b.length - 1; i >= 0; i--) {
			if (b[i] == '1')
				res += (int) Math.pow (2d, b.length - 1 - i);
			else if (b[i] != '0')
				exit ("mismatched input");
		}

		// int sign = (b.length == 32 && b[0] == '-') ? -1 : 1;
		// return sign * res;
		return res;
	}

	public static int htod (String s) {
		char[] h = s.toCharArray ();
		int res = 0;

		for (int i = 0; i < h.length; i++) {
			res *= 16;

			switch (h[i]) {
			case 'a':
				res += 10;
				break;
			case 'b':
				res += 11;
				break;
			case 'c':
				res += 12;
				break;
			case 'd':
				res += 13;
				break;
			case 'e':
				res += 14;
				break;
			case 'f':
				res += 15;
				break;
			default:
				res += h[i] - '0';
				break;
			}
		}

		// int sign = (h.length == 9 && h[0] == '-') ? -1 : 1;
		// return sign * res;
		return res;
	}

	public static int input (Scanner scn) {
		if (!scn.hasNextInt ())
			exit ("mismatched input");

		return scn.nextInt ();
	}

	public static void displayMenu () {
		System.out.println ("Menu:");
		System.out.println ("\t1) convert decimal to binary");
		System.out.println ("\t2) convert binary to decimal");
		System.out.println ("\t3) convert decimal to hexadecimal");
		System.out.println ("\t4) convert hexadecimal to decimal");
		System.out.println ("\t9) exit");
		System.out.print ("\nEnter your choise: ");
	}

	public static void exit (String msg) {
		System.err.println ("error: " + msg);
		System.exit (1);
	}

	public static void main (String[] args) {
		Scanner scn = new Scanner (System.in);
		boolean exit = false;

		while (!exit) {
			displayMenu ();

			switch (input (scn)) {
			case 1:
				System.out.print ("n ?= ");
				System.out.println ("dtob (n) = " + dtob (input (scn)) + '\n');
				break;
			case 2:
				System.out.print ("b ?= ");
				if (!scn.hasNext ())
					exit ("mismatched input");
				System.out.println ("btod (n) = " + btod (scn.next ()) + '\n');
				break;
			case 3:
				System.out.print ("n ?= ");
				System.out.println ("dtoh (n) = " + dtoh (input (scn)) + '\n');
				break;
			case 4:
				System.out.print ("h ?= ");
				if (!scn.hasNext ())
					exit ("mismatched input");
				System.out.println ("htod (n) = " + htod (scn.next ()) + '\n');
				break;
			case 9:
			default:
				exit = true;
				break;
			}
		}
	}
}
